package org.catspaw.cherubim.text.util;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URL;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

public class ExcelTemplate {

	private HSSFWorkbook	workbook;

	public ExcelTemplate(String templatePath) {
		URL url = ExcelTemplate.class.getResource(templatePath);
		if (url == null) {
			throw new IllegalArgumentException(
					"cannot find template file on path: " + templatePath);
		}
		try {
			workbook = new HSSFWorkbook(url.openStream());
		} catch (FileNotFoundException e) {
			throw new IllegalArgumentException(e);
		} catch (IOException e) {
			throw new IllegalStateException(e);
		}
	}

	public void setValue(int sheetNo, int rowNo, int cellNo, Object value) {
		HSSFSheet sheet = null;
		if (sheetNo >= workbook.getNumberOfSheets()) {
			sheet = workbook.createSheet();
		} else {
			sheet = workbook.getSheetAt(sheetNo);
		}
		HSSFRow row = null;
		if (rowNo >= sheet.getLastRowNum()) {
			row = sheet.createRow(rowNo);
		} else {
			row = sheet.getRow(rowNo);
		}
		HSSFCell cell = null;
		if (cellNo > row.getLastCellNum()) {
			cell = row.createCell(cellNo);
		} else {
			cell = row.getCell(cellNo);
		}
		if (value instanceof String) {
			HSSFRichTextString txt = new HSSFRichTextString((String) value);
			cell.setCellValue(txt);
		} else if (value instanceof Boolean) {
			cell.setCellValue((Boolean) value);
		} else if (value instanceof Double) {
			cell.setCellValue((Double) value);
		} else if (value instanceof Date) {
			cell.setCellValue((Date) value);
		} else if (value instanceof Calendar) {
			cell.setCellValue((Calendar) value);
		} else {
			HSSFRichTextString txt = new HSSFRichTextString(value.toString());
			cell.setCellValue(txt);
		}
	}

	public void setMatrix(int sheetNo, int rowOffset, int cellOffset,
			List<List<Object>> matrix) {
		for (int i = 0; i < matrix.size(); i++) {
			List<Object> row = matrix.get(i);
			setRow(sheetNo, rowOffset + i, cellOffset, row);
		}
	}

	public void setRow(int sheetNo, int rowOffset, int cellOffset,
			List<Object> row) {
		for (int i = 0; i < row.size(); i++) {
			Object value = row.get(i);
			setValue(sheetNo, rowOffset, cellOffset + i, value);
		}
	}

	public void setMatrix(int sheetNo, int rowOffset, int cellOffset,
			Object[][] matrix) {
		for (int i = 0; i < matrix.length; i++) {
			Object[] row = matrix[i];
			setRow(sheetNo, rowOffset + i, cellOffset, row);
		}
	}

	public void setRow(int sheetNo, int rowOffset, int cellOffset, Object[] row) {
		for (int i = 0; i < row.length; i++) {
			Object value = row[i];
			setValue(sheetNo, rowOffset, cellOffset + i, value);
		}
	}

	public void write(OutputStream os) throws IOException {
		workbook.write(os);
	}
}
